home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / misc / mirrorman_1_10b1.lha / MirrorManager-1.10b1 / rexx / ExamineIndex.mm < prev    next >
Text File  |  1994-06-24  |  19KB  |  594 lines

  1. /*rx
  2.     $VER: $Id: ExamineIndex.mm,v 1.9 1994/06/20 01:08:25 tf Exp $
  3.  
  4.     This script compares the LOCAL index file with the Aminet INDEX
  5.     file and reports differences in existance, path and comment.
  6.     If either COMMENT or RELOCATE keyword (or both) were given in the
  7.     command-line then the file position or filenote will be modified
  8.     respectively if needed.
  9.  
  10.     (The Aminet directory hierarchy can be created using 'MakeTree.rexx')
  11.  
  12.     This ARexx script needs the AmigaDOS commands "List", "Sort",
  13.     "Search", "Filenote", "Copy" and "Delete" available in your path.
  14.  
  15.     Initial revision by Tobias Ferber, 24-Feb-94
  16. */
  17.  
  18. options results
  19. options failat 10
  20.  
  21. call pragma('S',102400)
  22.  
  23. /* initialize globals */
  24.  
  25. mirrorpath  = ""  /* e.g. downloads:aminet/      */
  26. kickpath    = ""  /* e.g. incoming:              */
  27. localindex  = ""  /* e.g. downloads:aminet/LOCAL */
  28. masterindex = ""  /* e.g. downloads:aminet/INDEX */
  29.  
  30. fastprefix  = "FAST."
  31. tempfile    = "T:ExamineIndexTemp." || pragma('Id')
  32. template    = "FILE/K/A,WITH/K/A,PATH/K,RELOCATE/S,KICK/K,COMMENT/S,MAKEPATH/S,FAST/S,AUTO/S"
  33.  
  34. args        = ""
  35. cliopts     = ""
  36.  
  37. dg       = 0  /* gauge increment */
  38. gstepN   = 0
  39.  
  40. ESC      = '1b'x
  41.  
  42. signal on HALT
  43. signal on BREAK_C
  44. signal on BREAK_D
  45.  
  46.  
  47. /* parse args */
  48.  
  49. do ac=1 while ac <= arg()
  50.   av= arg(ac)
  51.   select
  52.     when upper(av) = "FILE" then do
  53.       if ac < arg() then do
  54.         ac= ac+1
  55.         localindex= arg(ac)
  56.         end
  57.       else exit bad_args('Missing local index filename after' ESC'bFILE'ESC'n keyword.')
  58.       end /* FILE */
  59.  
  60.     when upper(av) = "WITH" then do
  61.       if ac < arg() then do
  62.         ac= ac+1
  63.         masterindex= arg(ac)
  64.         end
  65.       else exit bad_args('Missing master index filename after' ESC'bWITH'ESC'n keyword.')
  66.       end /* WITH */
  67.  
  68.     when upper(av) = "PATH" then do
  69.       if ac < arg() then do
  70.         ac= ac+1
  71.         mirrorpath= arg(ac)
  72.         if words(mirrorpath) < 1 then mirrorpath= pragma('D')
  73.         end
  74.       else exit bad_args('Missing mirror pathname after' ESC'bPATH'ESC'n keyword.')
  75.       end /* PATH */
  76.  
  77.     when upper(av) = "KICK" then do
  78.       if ac < arg() then do
  79.         ac= ac+1
  80.         kickpath= arg(ac)
  81.         if words(kickpath) < 1 then kickpath= pragma('D')
  82.         end
  83.       else exit bad_args('Missing destination pathname after' ESC'bKICK'ESC'n keyword.')
  84.       end /* KICK */
  85.  
  86.     when upper(av) = "RELOCATE" then cliopts = cliopts || 'cd'
  87.     when upper(av) = "COMMENT"  then cliopts = cliopts || 'n'
  88.     when upper(av) = "MAKEPATH" then cliopts = cliopts || 'm'
  89.     when upper(av) = "FAST"     then cliopts = cliopts || 'f'
  90.     when upper(av) = "AUTO"     then cliopts = cliopts || 'a'
  91.  
  92.     otherwise exit bad_args('Unknown keyword:' ESC'b' || av || ESC'n')
  93.  
  94.   end /* select */
  95.  
  96. end /* do */
  97.  
  98. call pragma('W','N')
  99.  
  100.  
  101. /* try to get missing local index file */
  102.  
  103. if words(localindex) < 1 then do
  104.   cwd= strip(pragma('D'),'B','"')
  105.   REQUESTFILE DRAWER '"'cwd'"' TITLE '"Select local index file..."' NOICONS
  106.   if (rc=0) & (words(result) > 0) & (result ~= 'RESULT') then localindex= result
  107.   end
  108.  
  109. if words(localindex) < 1 then
  110.   exit bad_args("Not enough arguments for ExamineIndex...  Exiting...")
  111.  
  112. if ~exists(localindex) then do
  113.   REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  114.                 BODY    '"ExamineIndex failed to locate your local index*n*n' ||,
  115.                         ESC'c'ESC'b' || localindex || ESC'n'ESC'l'            || '"',
  116.                 GADGETS '"Exit"'
  117.   exit 10
  118.   end
  119.  
  120.  
  121. /* try to get missing master index path or filename */
  122.  
  123. if words(masterindex) < 1 then do
  124.   cwd= strip(pragma('D'),'B','"')
  125.   if pos('f',cliopts) > 0 then REQUESTFILE DRAWER '"'cwd'"' TITLE '"Select fast index path..."' DRAWERSONLY NOICONS
  126.                           else REQUESTFILE DRAWER '"'cwd'"' TITLE '"Select master index file..."' NOICONS
  127.   if (rc=0) & (words(result) > 0) & (result ~= 'RESULT') then masterindex= result
  128.   end
  129.  
  130. if words(masterindex) < 1 then
  131.   exit bad_args("Not enough arguments for ExamineIndex...  Exiting...")
  132.  
  133. if ~exists(masterindex) then do
  134.   REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  135.                 BODY    '"ExamineIndex failed to locate your master index*n*n' ||,
  136.                         ESC'c'ESC'b' || masterindex || ESC'n'ESC'l'            || '"',
  137.                 GADGETS '"Exit"'
  138.   exit 10
  139.   end
  140.  
  141.  
  142. /* eventually try to get missing from path */
  143.  
  144. if (pos('cd',cliopts) > 0) | (pos('n',cliopts) > 0) | (pos('m',cliopts) > 0) then do
  145.   if words(mirrorpath) < 1 then do
  146.     cwd= strip(pragma('D'),'B','"')
  147.     REQUESTFILE DRAWER '"'cwd'"' TITLE '"Select the mirror directory..."' DRAWERSONLY NOICONS
  148.     if (rc=0) & (words(result) > 0) & (result ~= 'RESULT') then mirrorpath= result
  149.     end
  150.  
  151.   if words(mirrorpath) < 1 then
  152.     exit bad_args("Not enough arguments for ExamineIndex...  Exiting...")
  153.  
  154.   if ~exists(mirrorpath) then do
  155.     REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  156.                   BODY    '"ExamineIndex failed to locate your mirror directory*n*n' ||,
  157.                           ESC'c'ESC'b' || mirrorpath || ESC'n'ESC'l'                 || '"',
  158.                   GADGETS '"Exit"'
  159.     exit 10
  160.     end
  161.   end
  162.  
  163.  
  164. /* eventually create the kick path */
  165.  
  166. if words(kickpath) > 0 then do
  167.   if ~exists(kickpath) & canexist(kickpath) then do
  168.     if pos('m',cliopts) > 0 then call makepath(kickpath)
  169.     else do
  170.       REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  171.                     BODY    '"Destination path*n*n'                      ||,
  172.                             ESC'c'ESC'b' || kickpath || ESC'n'ESC'l*n*n' ||,
  173.                             'does not exist.  Shall I create it?'        || '"',
  174.                     GADGETS '"_Yes|_No"'
  175.       if result > 0 then do
  176.         if result > 1 then cliopts = cliopts || 'm'
  177.         call makepath(kickpath)
  178.         end
  179.       else do
  180.         REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  181.                       BODY    '"Operation canceled."',
  182.                       GADGETS '"Exit"'
  183.         exit
  184.         end
  185.       end
  186.     if exists(kickpath) then MESSAGE '"'kickpath'   [created]"'
  187.     end
  188.  
  189.   if ~exists(kickpath) then do
  190.     REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  191.                   BODY    '"ExamineIndex failed to create your destination path*n*n' ||,
  192.                           ESC'c'ESC'b' || kickpath || ESC'n'ESC'l'                   || '"',
  193.                   GADGETS '"Exit"'
  194.     exit 10
  195.     end
  196.   end
  197.  
  198.  
  199. signal on ERROR
  200. signal on IOERR
  201.  
  202. signal on FAILURE
  203. /*signal on NOVALUE*/
  204. signal on SYNTAX
  205.  
  206.  
  207. CALL init_gauge(localindex,2)
  208.  
  209.  
  210. /* do the hard part */
  211.  
  212. if ~open('fp',localindex,'R') then do
  213.   REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  214.                 BODY    '"Could not open local index file*n*n'     ||,
  215.                         ESC'c'ESC'b' || localindex || ESC'n'ESC'l' || '"',
  216.                 GADGETS '"Exit"'
  217.   exit 10
  218.   end
  219.  
  220. do until eof('fp')
  221.  
  222.   str= strip( readln('fp') )
  223.   if (words(str) > 0) & (left(str,1) ~= '|') then do
  224.     parse var str fname pname fsize comment
  225.  
  226.     if pos('f',cliopts) > 0 then masterfile = tackon(masterindex,fastprefix) || upper(left(fname,1))
  227.                             else masterfile = masterindex
  228.  
  229.     if exists(masterfile) then do
  230.       MESSAGE transquote('Searching for "'tackon(pname,fname)'" in "'masterfile'" ...')
  231.       if pname = '.' then pname = ""
  232.  
  233.       signal off ERROR
  234.       address command searchcmd(fname,masterfile)
  235.       signal on ERROR
  236.  
  237.       CALL step_gauge(1)
  238.  
  239.       if ~open('tfp',tempfile,'R') then do
  240.           REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  241.                         BODY    '"Search failed.  Could not open*n*n'    ||,
  242.                                 ESC'c'ESC'b' || tempfile || ESC'n'ESC'l' || '"',
  243.                         GADGETS '"Exit"'
  244.         call close('fp')
  245.         exit 10
  246.         end
  247.  
  248.       master_pname   = ""
  249.       master_comment = ""
  250.       matches = 0
  251.  
  252.       do until eof('tfp') | matches > 1
  253.         str= strip( readln('tfp') )
  254.  
  255.         if words(str) > 0 then do
  256.           parse var str f d . 38 c
  257.  
  258.           if f = fname then do
  259.             if matches = 0 then do
  260.               master_pname= d
  261.               master_comment= c
  262.               matches= matches + 1
  263.               end
  264.             else if (master_pname ~= d) | (master_comment ~= c) then matches= matches + 1
  265.             end
  266.  
  267.           end
  268.  
  269.           /* else we matched the comment */
  270.  
  271.         end /* scan ifp */
  272.  
  273.       call close('tfp')
  274.       address command 'Delete QUIET FILE "' || tempfile || '"'
  275.  
  276.       /**/
  277.  
  278.       select /* #of matches */
  279.  
  280.         when matches = 1 then do
  281.           fromfile = tackon( tackon(mirrorpath, pname       ), fname)
  282.           tofile   = tackon( tackon(mirrorpath, master_pname), fname)
  283.  
  284.           if exists(fromfile) then do   /* Maybe someone deleted our fromfile meanwhile... */
  285.  
  286.             if comment ~= master_comment then do
  287.               if pos('n',cliopts) < 1 then
  288.                 MESSAGE transquote('Filenote of "'fname'" has changed from "'comment'" to "'master_comment'"')
  289.               else do
  290.                 MESSAGE transquote('Changing filenote of "'fname'" from "'comment'" to "'master_comment'"')
  291.                 address command 'Filenote QUIET FILE' fromfile 'COMMENT' transquote(master_comment)
  292.                 end
  293.               end /* comment ~= master_comment */
  294.  
  295.             if pname ~= master_pname then do
  296.  
  297.               if pos('cd',cliopts) < 1 then
  298.                 MESSAGE transquote('File "'fname'" has moved from "'pname'" to "'master_pname'"')
  299.  
  300.               else do
  301.                 MESSAGE transquote('Moving "'fname'" from "'pname'" to "'master_pname'"')
  302.                 destpath= tackon(mirrorpath,master_pname)
  303.                 if ~exists(destpath) & canexist(destpath) then do
  304.                   if pos('m',cliopts) > 0 then call makepath(destpath)
  305.                   else do
  306.                     REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  307.                                   BODY    '"Destination path*n*n'                      ||,
  308.                                           ESC'c'ESC'b' || destpath || ESC'n'ESC'l*n*n' ||,
  309.                                           'does not exist.  Shall I create it?'        || '"',
  310.                                   GADGETS '"_Yes|_All|_No"'
  311.                     if result > 0 then do
  312.                       if result > 1 then cliopts = cliopts || 'm'
  313.                       call makepath(destpath)
  314.                       end
  315.                     end
  316.                   if exists(destpath) then MESSAGE '"'destpath'   [created]"'
  317.                   end
  318.  
  319.                 if exists(destpath) then do
  320.                   if exists(tofile) then do
  321.                     if pos('r',cliopts) > 0 then address command 'Copy QUIET CLONE FROM "'fromfile'" TO "'tofile'"'
  322.                     else do
  323.                       REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  324.                                     BODY    '"'ESC'c'ESC'b' || tofile || ESC'n'ESC'l*n*n' ||,
  325.                                             'already exists.  Shall I replace it?'        || '"',
  326.                                     GADGETS '"_Yes|_All|_No"'
  327.                       if result > 0 then do
  328.                         if result > 1 then cliopts = cliopts || 'r'
  329.                         address command 'Copy QUIET CLONE FROM "'fromfile'" TO "'tofile'"'
  330.                         end
  331.                       else MESSAGE transquote(tofile 'not replaced')
  332.                       end
  333.                     end
  334.                   else address command 'Copy QUIET CLONE FROM "'fromfile'" TO "'tofile'"'
  335.  
  336.                   if exists(tofile) then address command 'Delete QUIET FILE "'fromfile'"'
  337.                   end
  338.  
  339.                 else MESSAGE transquote('Warning: "'fname'" ignored.  (Destination path "'destpath'" not created)')
  340.                 end
  341.               end /* pname ~= master_pname */
  342.  
  343.             end
  344.           else MESSAGE transquote('Warning: "'fromfile'" does not exist anymore ... ignored')
  345.           end /* matches = 1 */
  346.  
  347.         when matches = 0 then do
  348.           MESSAGE transquote('Warning: file "'fname'" not found in master index file "'masterfile'"')
  349.  
  350.           if words(kickpath) > 0 then do
  351.  
  352.             fromfile = tackon(tackon(mirrorpath, pname), fname)
  353.             tofile   = tackon(kickpath, fname)
  354.  
  355.             if exists(fromfile) then do
  356.               if exists(tofile) then do
  357.                 if (pos('r',cliopts) < 1) then do
  358.                   REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  359.                                 BODY    '"'ESC'c'ESC'b' || tofile || ESC'n'ESC'l*n*n' ||,
  360.                                         'already exists.  Shall I replace it?'        || '"',
  361.                                 GADGETS '"_Yes|_All|_No"'
  362.                   if result > 0 then do
  363.                     if result > 1 then cliopts = cliopts || 'r'
  364.                     MESSAGE transquote('Overwriting "'tofile'" with "'fromfile'"')
  365.                     address command 'Copy QUIET CLONE FROM "'fromfile'" TO "'tofile'"'
  366.                     end
  367.                   else MESSAGE transquote(tofile 'not replaced')
  368.                   end
  369.                 else do
  370.                   MESSAGE transquote('Overwriting "'tofile'" with "'fromfile'"')
  371.                   address command 'Copy QUIET CLONE FROM "'fromfile'" TO "'tofile'"'
  372.                   end
  373.                 end
  374.               else do
  375.                 MESSAGE transquote('Moving "'fromfile'" to "'kickpath'" ...')
  376.                 address command 'Copy QUIET CLONE FROM "'fromfile'" TO "'tofile'"'
  377.                 end
  378.  
  379.               if exists(tofile) then address command 'Delete QUIET FILE "'fromfile'"'
  380.               end /* exists(fromfile) */
  381.  
  382.             else MESSAGE transquote('Warning: "'fromfile'" does not exist anymore ... ignored')
  383.             end
  384.           end /* matches = 0 */
  385.  
  386.         otherwise do
  387.           MESSAGE transquote('Warning: filename "'fname'" is ambiguous... skipped')
  388.           end
  389.  
  390.         end /* select */
  391.  
  392.       end /* exists(masterfile) */
  393.  
  394.     else MESSAGE transquote('Master index file "'masterfile'" does not exist ... "'fname'" skipped')
  395.     end /* have fname */
  396.  
  397.   CALL step_gauge(1)
  398.  
  399.   end /* do scan fp */
  400.  
  401. call close('fp')
  402. step_gauge(100)
  403. MESSAGE '"done."'
  404. IF POS('a',cliopts) > 0 THEN MESSAGE CLOSE
  405. EXIT 0
  406.  
  407. /**/
  408.  
  409. bad_args: PROCEDURE EXPOSE template ESC
  410.   PARSE ARG msg
  411.  
  412.   REQUESTCHOICE TITLE   '"ExamineIndex Request"',
  413.                 BODY    '"' || msg || '*n*n'                     ||,
  414.                         'ExamineIndex args template:*n*n'        ||,
  415.                         ESC'c'ESC'b' || template || ESC'n'ESC'l' || '"',
  416.                 GADGETS '"Okay"'
  417.   RETURN 0
  418.  
  419.  
  420. /* generate the search command string */
  421.  
  422. searchcmd: PROCEDURE EXPOSE tempfile
  423.   PARSE ARG pattern,file
  424.   return 'Search NONUM > "'tempfile'" FROM "'file'" SEARCH "'pattern'"'
  425.   /*return 'AGrep > "'tempfile'"' '"'pattern'"' '"'file'"'*/
  426.  
  427. /*@*/
  428.  
  429.  
  430. /* translate '"' into '*"' and '*' into '**' */
  431.  
  432. transquote: procedure
  433.   parse arg s
  434.   t= s
  435.   q= max( lastpos('*',s), lastpos('"',s) )
  436.   do while q > 0
  437.     t= insert('*',t,q-1,1)
  438.     s= left(s,q-1)
  439.     q= max( lastpos('*',s), lastpos('"',s) )
  440.     end
  441.   return '"' || t || '"'
  442.  
  443.  
  444. /* return the non-file part of a pathname */
  445.  
  446. pathonly: procedure
  447.   parse arg path
  448.   if (words(path) > 0) & (right(path,1) ~= ':') then do
  449.     if right(path,1) = '/' then path= left(path,length(path)-1)
  450.     if lastpos('/',path) > lastpos(':',path) then path= left(path,lastpos('/',path)-1)
  451.                                              else path= left(path,lastpos(':',path))
  452.     end
  453.   return path
  454.  
  455.  
  456. /* return the file part of a pathname */
  457.  
  458. fileonly: procedure
  459.   parse arg path
  460.   if right(path,1) = '/' then path= left(path,length(path)-1)
  461.   p= max( lastpos(':',path), lastpos('/',path) )
  462.   if(p>0) then return substr(path,p+1)
  463.           else return path
  464.  
  465.  
  466. /* concatenate the filename to the pathname and return the resulting string */
  467.  
  468. tackon: procedure
  469.   parse arg path,file
  470.   do while left(file,1) = '/'
  471.     file= substr(file,2)
  472.     path= pathonly(path)
  473.     end
  474.   if (words(path) > 0) & (right(path,1) ~= '/') & (right(path,1) ~= ':') then path= path || '/'
  475.   if (right(file,1) = '/') then file= left(file,length(file)-1)
  476.   return path || file
  477.  
  478.  
  479. /* create all non-existant directories in a path */
  480.  
  481. makepath: procedure
  482.   parse arg path
  483.   if right(path,1) = '/' then path= left(path,length(path)-1)
  484.   if ~exists(path) then do
  485.     call makepath( pathonly(path) )
  486.     address command 'MakeDir NAME "'path'"'
  487.     end
  488.   return 0
  489.  
  490.  
  491. /*
  492.  * return   1  if the device or volume name in given pathname exists
  493.  *             or if no device or volume was present (current device)
  494.  *          0  if the device or volume name does not exist
  495.  */
  496.  
  497. canexist: procedure
  498.   parse upper arg path
  499.   if pos(':',path) < 1 then return 1 /* current device */
  500.   call pragma('W','N')
  501.   return exists( left(path,lastpos(':',path)) )
  502.  
  503.  
  504. /* stretch the blue completion bar */
  505.  
  506. step_gauge: PROCEDURE EXPOSE dg gstepN
  507.   ARG increment
  508.   gstepN= gstepN + 1
  509.   c= MIN(TRUNC(gstepN * increment * dg),100)
  510.   COMPLETE c
  511.   IF c >= 100 THEN WORKING '"done."'
  512.   RETURN 0
  513.  
  514.  
  515. /* initialize the gauge increment by counting the #of steps to be performed */
  516.  
  517. init_gauge: PROCEDURE EXPOSE dg gstepN
  518.   PARSE ARG fname,steps_per_entry
  519.  
  520.   dg = 0         /* gauge increment */
  521.   gstepN = 0     /* #of performed steps */
  522.  
  523.   IF OPEN('fp',fname,'R') THEN DO
  524.     numentries= 0
  525.     DO UNTIL EOF('fp')
  526.       IF WORDS(READLN('fp')) > 0 THEN
  527.         numentries= numentries+1
  528.       END
  529.     WORKING '"Processing' numentries 'entries..."'
  530.     dg = 100 / (numentries * steps_per_entry)
  531.     CALL SEEK('fp',0,'B')
  532.     CALL CLOSE('fp')
  533.     END
  534.  
  535.   MESSAGE CLEAR; MESSAGE OPEN
  536.   COMPLETE 0
  537.   RETURN 0
  538.  
  539.  
  540. /* error/break handling */
  541.  
  542. IOERR:
  543. ERROR:
  544.   err= rc
  545.   ESC = '1b'x
  546.  
  547.   signal off ERROR
  548.   signal off IOERR
  549.  
  550.   WORKING '"I/O problem trapped... Execution halted."'
  551.   MESSAGE '"I/O problem trapped... Execution halted."'
  552.  
  553.   REQUESTCHOICE TITLE   '"ExamineIndex Error Trap' err'"',
  554.                 BODY    '"There was a problem with external I/O in line' sigl '...*n' ||,
  555.                         ESC'c'ESC'b' || ERRORTEXT(err) || ESC'n'ESC'l'                || '"',
  556.                 GADGETS '"I''ll better exit"'
  557.   exit
  558.  
  559.  
  560. FAILURE:
  561. NOVALUE:
  562. SYNTAX:
  563.   err= rc
  564.   ESC = '1b'x
  565.  
  566.   signal off FAILURE
  567.   signal off NOVALUE
  568.   signal off SYNTAX
  569.  
  570.   WORKING '"Internal problem trapped... Execution halted."'
  571.   MESSAGE '"Internal problem trapped... Execution halted."'
  572.  
  573.   REQUESTCHOICE TITLE   '"ExamineIndex Internal Error' err'"',
  574.                 BODY    '"ExamineIndex seems to have an internal problem in line' sigl '...*n' ||,
  575.                         ESC'c'ESC'b' || ERRORTEXT(err) || ESC'n'ESC'l'                         || '"',
  576.                 GADGETS '"I''ll better exit"'
  577.   exit
  578.  
  579.  
  580. HALT:
  581. BREAK_C:
  582. BREAK_D:
  583.   signal off HALT
  584.   signal off BREAK_C
  585.   signal off BREAK_D
  586.  
  587.   WORKING '"Break signal trapped... Execution halted."'
  588.   MESSAGE '"Break signal trapped... Execution halted."'
  589.  
  590.   REQUESTCHOICE TITLE   '"ExamineIndex Break Trap"',
  591.                 BODY    '"Script execution halted."',
  592.                 GADGETS '"Stop"'
  593.   exit
  594.